package com.huterox.spring.framework.beans.suports;

import com.huterox.spring.framework.beans.config.HUBeanDefinition;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Properties;

public class HUBeanDefinitionReader {

    private Properties contextConfig = new Properties();
    //需要被注册到容器里面的类
    private List<String> registryBeanClass = new ArrayList<>();
    public HUBeanDefinitionReader(String[] configLocations) {
        //1.加载配置文件并解析,当前只支持properties先这样处理
        doLoadConfig(configLocations[0]);
        //2.读取配置文件，并且封装为BeanDefinition对象
        doScanner(contextConfig.getProperty("scanPackage"));
        doLoadBeanDefinitions();
    }

    //负责读取配置文件
    public List<HUBeanDefinition> doLoadBeanDefinitions() {
        //这里注意此时我们存入的是类的包名com.xx.xx.xx
        List<HUBeanDefinition> result = new ArrayList<>();
        try {

            for (String className:registryBeanClass){
                Class<?> beanClass = Class.forName(className);
                if(beanClass.isInterface()) continue;
                //把类名放在里面 beanClass.getName()是获取全包名
                result.add(doCreateBeanDefition(toLowerFirstCase(beanClass.getSimpleName()), beanClass.getName()));
                //把这玩意的接口也给它
                for(Class<?> InfClass:beanClass.getInterfaces()){
                    result.add(doCreateBeanDefition(InfClass.getSimpleName(), beanClass.getName()));
                }
            }

        }catch (Exception e){
            e.printStackTrace();
        }

        return result;
    }

    private HUBeanDefinition doCreateBeanDefition(String factoryBeanName, String beanClassName) {
        HUBeanDefinition beanDefinition = new HUBeanDefinition();
        beanDefinition.setFactoryBeanName(factoryBeanName);
        beanDefinition.setBeanClassName(beanClassName);
        return beanDefinition;
    }


    private void doLoadConfig(String contextproperties) {
        InputStream is = this.getClass().getClassLoader().getResourceAsStream(contextproperties);
        try {
            contextConfig.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }


    private void doScanner(String scanPackage){
        // 扫描我们想要控制的那个包下面的所有类
        //存进去的是 com.huterox.test.xx(类名)
        URL url = this.getClass().getClassLoader().getResource("/" + scanPackage.replaceAll("\\.", "/"));

        assert url != null;
        File classDir = new File(url.getFile());
        for(File file: Objects.requireNonNull(classDir.listFiles())){
            if(file.isDirectory()){
                this.doScanner(scanPackage+"."+file.getName());
            }else {
                if (!file.getName().endsWith(".class")) continue;
                String clazzName = (scanPackage + "." + file.getName().replace(".class", ""));
                registryBeanClass.add(clazzName);
            }
        }
    }

    private String toLowerFirstCase(String simpleName){
        //字母转换，符合javabean标准
        char[] chars = simpleName.toCharArray();
        if(67<=(int)chars[0]&&(int)chars[0]<=92)
            chars[0] +=32;
        return String.valueOf(chars);
    }

    public Properties getConfig() {
        return this.contextConfig;
    }
}
